From: Stefano Stabellini Date: Wed, 31 Aug 2011 14:23:12 +0000 (+0100) Subject: xen: fix hvm_domain_use_pirq's behavior X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~9930 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=79858fee307c1b47eef66a0c280d23b650e8d906;p=xen.git xen: fix hvm_domain_use_pirq's behavior hvm_domain_use_pirq should return true when the guest is using a certain pirq, no matter if the corresponding event channel is currently enabled or disabled. As an additional complication, qemu is going to request pirqs for passthrough devices even for Xen unaware HVM guests, so we need to wait for an event channel to be connected before considering the pirq of a passthrough device as "in use". Signed-off-by: Stefano Stabellini --- diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 267b96faff..4d0c590687 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -2027,6 +2027,5 @@ int unmap_domain_pirq_emuirq(struct domain *d, int pirq) bool_t hvm_domain_use_pirq(const struct domain *d, const struct pirq *pirq) { return is_hvm_domain(d) && pirq && - pirq->arch.hvm.emuirq != IRQ_UNBOUND && - pirq->evtchn != 0; + pirq->arch.hvm.emuirq != IRQ_UNBOUND; } diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index 35fbbeb348..d51f4a081f 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -196,9 +196,6 @@ int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p, if ( ret == 0 ) *pirq_p = pirq; - if ( !ret && is_hvm_domain(d) ) - map_domain_emuirq_pirq(d, pirq, IRQ_PT); - done: spin_unlock(&d->event_lock); spin_unlock(&pcidevs_lock); @@ -271,7 +268,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) v->domain->arch.pv_domain.pirq_eoi_map ) evtchn_unmask(pirq->evtchn); if ( !is_hvm_domain(v->domain) || - pirq->arch.hvm.emuirq == IRQ_PT ) + domain_pirq_to_irq(v->domain, eoi.irq) > 0 ) pirq_guest_eoi(pirq); spin_unlock(&v->domain->event_lock); ret = 0; @@ -331,7 +328,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) break; irq_status_query.flags = 0; if ( is_hvm_domain(v->domain) && - domain_pirq_to_emuirq(v->domain, irq) != IRQ_PT ) + domain_pirq_to_irq(v->domain, irq) <= 0 ) { ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0; break; diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 631bbede22..0628120c24 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -366,6 +366,9 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind) bind->port = port; + if ( is_hvm_domain(d) && domain_pirq_to_irq(d, pirq) > 0 ) + map_domain_emuirq_pirq(d, pirq, IRQ_PT); + out: spin_unlock(&d->event_lock); @@ -419,6 +422,8 @@ static long __evtchn_close(struct domain *d1, int port1) pirq->evtchn = 0; pirq_cleanup_check(pirq, d1); unlink_pirq_port(chn1, d1->vcpu[chn1->notify_vcpu_id]); + if ( is_hvm_domain(d1) && domain_pirq_to_irq(d1, pirq->pirq) > 0 ) + unmap_domain_pirq_emuirq(d1, pirq->pirq); break; }